昨天終於解釋完Polymorphism,今天接著來聊聊為什麼要用virtual function虛擬函數。
先來複習一下昨天的code:
#include <iostream>
using namespace std;
class Family{
    protected:
    string Name;
public:
     void setname(string name){
        Name = name;
    }
     string getname(){
        return "Family:" + Name;
    }
};
class Mom:public Family{
public:
    string getname(){
        return "Mom's name is " + Name;
    }
    
};
class Dad:public Family{
public:
     string getname(){
        return "Dad's name is "+ Name;
    }
  
};
class Son:public Mom{
public:
    string getname(){
        return "Son's name is " + Name;
    }
    
};
int main()
{   
    string x, y, z;
    Family f;
    Mom m;
    Dad d;
    Son s;
    Family *f1 = &m;
    Family *f2 = &d;
    Family *f3 = &s;
    cout <<"Type mom's name: ";
    cin >> x;
    f1 -> setname(x);
    cout <<"Type dad's name: ";
    cin >> y;
    f2 -> setname(y);
    cout <<"Type son's name: ";
    cin >> z;
    f3 -> setname(z);
    
    cout << m.getname() << endl;
    cout << d.getname() << endl;
    cout << s.getname() << endl;
    return 0;
}
讚,接著可以注意到,為什麼在getname()時都還要用m,而不是直接用已經裝好m記憶體地址的f1?
那這樣大費周章的放指標f1好像也沒什麼意義,直接用m就好了嘛。
那我們把cout << m.getname() << endl;
改成cout << f1 -> getname() << endl;看看好了。
假設我們輸入媽媽的名字是"Rose"。
預期輸出:Mom's name: Rose
實際輸出:Family: Rose
哪尼怎麼會這樣~~
因為因為, f1指向的是Family class:Family f1* = &m;
所以為了讓程式知道我們指的是哪個,可以在base class加上virtual:
class Family{
    protected:
    string Name;
public:
     void setname(string name){
        Name = name;
    }
     virtual string getname(){
        return "Family:" + Name;
    }
};
現在再來試一次,如下:cout << f1 -> getname() << endl;
輸出: Mom's name: Rose
就解決問題了~
Reference: cplusplus.com, The Cherno, Practical C++ Programming, w3school, wikipedia, thenewboston,